"""
Gua CLI 主类 - 基于 Linus 设计哲学
简单胜过复杂 - 将 granian 的复杂性封装为简单接口
"""

import os
import sys
import argparse
from typing import List, Dict, Any, Optional

from .presets import PresetManager
from .generator import CommandGenerator


class GuaCLI:
    """Gua CLI 主类 - 简化的 granian 命令包装器"""
    
    def __init__(self):
        self.presets = PresetManager()
        self.generator = CommandGenerator()
    
    def run(self, args: List[str] = None) -> int:
        """运行 CLI
        
        Args:
            args: 命令行参数，如果为 None 则使用 sys.argv
            
        Returns:
            退出码
        """
        if args is None:
            args = sys.argv[1:]
        
        try:
            config = self.parse_args(args)
            return self.execute_command(config)
        except KeyboardInterrupt:
            print("\n用户中断操作")
            return 130
        except Exception as e:
            print(f"错误: {e}")
            return 1
    
    def parse_args(self, args: List[str]) -> Dict[str, Any]:
        """解析命令行参数
        
        Args:
            args: 命令行参数列表
            
        Returns:
            解析后的配置字典
        """
        parser = argparse.ArgumentParser(
            prog="gua",
            description="Gua CLI - 基于 Linus 设计哲学的 granian 命令包装器"
        )
        
        # 应用参数
        parser.add_argument(
            "app",
            nargs="?",
            help="应用标识符 (如: app:app)，默认自动检测"
        )
        
        # 核心参数
        parser.add_argument(
            "--port", "-p",
            type=int,
            default=8000,
            help="端口号 (默认: 8000)"
        )
        
        parser.add_argument(
            "--host",
            default="0.0.0.0",
            help="主机地址 (默认: 0.0.0.0)"
        )
        
        parser.add_argument(
            "--mode", "-m",
            choices=["dev", "prod", "example"],
            default="dev",
            help="运行模式 (默认: dev)"
        )
        
        parser.add_argument(
            "--workers", "-w",
            type=int,
            default=None,
            help="工作进程数 (默认: 模式自动设置)"
        )
        
        # 静态文件参数
        parser.add_argument(
            "--static",
            help="静态文件目录路径"
        )
        
        parser.add_argument(
            "--static-route",
            default="/static",
            help="静态文件路由前缀 (默认: /static)"
        )
        
        # 其他选项
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="显示将要执行的命令而不实际执行"
        )
        
        parser.add_argument(
            "--example-info",
            action="store_true",
            help="显示示例启动信息而不实际启动服务"
        )
        
        parser.add_argument(
            "--version",
            action="version",
            version="gua 0.1.0"
        )
        
        # 解析参数，但先处理透传参数
        extra_args = []
        if "--" in args:
            # 找到 -- 分隔符，获取后续所有参数
            dash_index = args.index("--")
            extra_args = args[dash_index + 1:]
            # 从参数列表中移除 -- 及后续参数
            args = args[:dash_index]
        
        parsed_args = parser.parse_args(args)
        parsed_args.extra_args = extra_args
        
        # 构建配置，优先使用命令行参数，然后是环境变量
        config = {
            "app": parsed_args.app,
            "port": parsed_args.port if parsed_args.port != 8000 else self._get_env_var("GUA_PORT", 8000),
            "host": parsed_args.host if parsed_args.host != "0.0.0.0" else self._get_env_var("GUA_HOST", "0.0.0.0"),
            "mode": parsed_args.mode if parsed_args.mode != "dev" else self._get_env_var("GUA_MODE", "dev"),
            "workers": parsed_args.workers,
            "static": parsed_args.static,
            "static_route": parsed_args.static_route,
            "extra_args": parsed_args.extra_args,
            "dry_run": parsed_args.dry_run,
            "example_info": parsed_args.example_info
        }
        
        return config
    
    def execute_command(self, config: Dict[str, Any]) -> int:
        """执行命令
        
        Args:
            config: 配置字典
            
        Returns:
            退出码
        """
        # 检测应用
        app = self._resolve_app(config["app"])
        if not app:
            raise ValueError("无法确定应用。请指定应用标识符 (如: app:app)")
        
        # 验证应用格式
        if not self.generator.validate_app_format(app):
            raise ValueError(f"无效的应用格式: {app}")
        
        # 应用预设配置
        base_config = {
            "host": config["host"],
            "port": config["port"],
            "workers": config["workers"] or self.presets.get_workers_count(config["mode"])
        }
        
        preset_config = self.presets.apply_preset(config["mode"], base_config)
        
        # 生成 granian 命令
        cmd = self.generator.generate_granian_command(
            app=app,
            config=preset_config,
            static_dir=config["static"],
            static_route=config["static_route"],
            extra_args=config["extra_args"]
        )
        
        # 显示示例启动信息
        if config["example_info"]:
            self._show_example_info(app, config, cmd)
            return 0
        
        # 显示命令
        if config["dry_run"]:
            print(f"将要执行的命令: {self.generator.format_command_for_display(cmd)}")
            return 0
        
        # 执行命令
        return self._run_command(cmd)
    
    def _resolve_app(self, app: Optional[str]) -> Optional[str]:
        """解析应用标识符
        
        Args:
            app: 用户指定的应用
            
        Returns:
            解析后的应用标识符
        """
        if app:
            return app
        
        # 自动检测
        return self.generator.detect_app_from_context()
    
    def _run_command(self, cmd: List[str]) -> int:
        """运行命令 - 使用 execvp 替换当前进程
        
        Args:
            cmd: 命令列表
            
        Returns:
            退出码（实际上不会返回，因为进程被替换）
        """
        try:
            # 显示执行的命令
            print("🚀 启动 Gua 应用...")
            print(f"📋 执行命令: {self.generator.format_command_for_display(cmd)}")
            print()
            
            # 使用 execvp 替换当前进程
            # 这是 Unix 系统启动服务的标准做法
            os.execvp(cmd[0], cmd)
            
        except FileNotFoundError:
            print("错误: 找不到 granian 命令。请确保已安装 granian: pip install granian")
            return 1
        except Exception as e:
            print(f"执行命令时发生错误: {e}")
            return 1
    
    def _get_env_var(self, name: str, default: Any) -> Any:
        """获取环境变量
        
        Args:
            name: 环境变量名
            default: 默认值
            
        Returns:
            环境变量值或默认值
        """
        value = os.getenv(name)
        if value is None:
            return default
        
        # 尝试转换类型 - 先检查更具体的类型
        if isinstance(default, bool):
            return value.lower() in ("true", "1", "yes", "on")
        elif isinstance(default, int):
            try:
                return int(value)
            except ValueError:
                return default
        
        return value
    
    # 示例信息配置 - 数据驱动设计
    EXAMPLE_CONFIGS = {
        "simple_app": {
            "title": "🚀 启动极简应用示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看主页",
                        "🔗 访问 http://localhost:8000/api/users/123 查看API",
                        "❌ 访问 http://localhost:8000/api/error 查看错误处理"
                    ]
                }
            ]
        },
        "auth_demo": {
            "title": "🔐 认证中间件演示",
            "sections": [
                {
                    "type": "separator",
                    "char": "=",
                    "length": 50
                },
                {
                    "type": "info",
                    "items": [
                        "📋 公开路径: ['/login', '/register', '/health']",
                        "🔒 所有其他路径都需要认证",
                        "🔑 认证令牌: 'Bearer secret-token'"
                    ]
                },
                {
                    "type": "separator",
                    "char": "=",
                    "length": 50
                },
                {
                    "type": "subsection",
                    "title": "🧪 测试命令:",
                    "sections": [
                        {
                            "type": "subsection",
                            "title": "📡 公开接口（无需认证）:",
                            "items": [
                                "  curl http://localhost:8000/login",
                                "  curl http://localhost:8000/register",
                                "  curl http://localhost:8000/health"
                            ]
                        },
                        {
                            "type": "subsection",
                            "title": "🔒 受保护接口（需要认证）:",
                            "items": [
                                "  curl http://localhost:8000/  # 将失败",
                                "  curl http://localhost:8000/api/users  # 将失败",
                                "  curl -H 'Authorization: Bearer secret-token' http://localhost:8000/  # 将成功",
                                "  curl -H 'Authorization: Bearer secret-token' http://localhost:8000/api/users  # 将成功"
                            ]
                        }
                    ]
                }
            ]
        },
        "streaming_api": {
            "title": "🌊 Gua框架流式处理示例",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 体验流式响应",
                        "🔢 /stream - 数字流 (每500ms)",
                        "⚡ /quick-stream - 快速流 (每200ms)",
                        "💬 /chat-stream - AI对话 (逐字输出)",
                        "📡 /events - SSE事件流"
                    ]
                }
            ]
        },
        "ai_streaming": {
            "title": "🤖 启动AI流式响应示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 体验AI对话",
                        "🌐 连接 ws://localhost:8000/ws 体验WebSocket对话"
                    ]
                }
            ]
        },
        "websocket_app": {
            "title": "🌐 启动WebSocket聊天示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看聊天室",
                        "📊 访问 /status 查看连接状态",
                        "🔌 连接 ws://localhost:8000/ws 体验WebSocket"
                    ]
                }
            ]
        },
        "middleware_app": {
            "title": "🔐 启动中间件示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看主页（公开）",
                        "🌐 访问 /public 查看公共数据（无需认证）",
                        "🔑 访问 /login 查看登录页面（公开）",
                        "📝 访问 /register 查看注册页面（公开）",
                        "🔒 访问 /admin 查看管理员数据（需要认证）",
                        "📊 访问 /api/data 查看API数据（需要认证）"
                    ]
                },
                {
                    "type": "info",
                    "items": [
                        "🔒 新的认证中间件：默认保护所有路径，只列出公开路径",
                        "📋 公开路径列表: ['/', '/public']",
                        "🔐 所有其他路径都需要认证",
                        "认证提示：在请求头中添加 'Authorization: Bearer admin-token'"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "🧪 测试命令示例：",
                    "sections": [
                        {
                            "type": "info",
                            "items": [
                                "# 公开接口访问（无需认证）",
                                "  curl http://localhost:8000/",
                                "  curl http://localhost:8000/public",
                                "  curl http://localhost:8000/login"
                            ]
                        },
                        {
                            "type": "info",
                            "items": [
                                "# 受保护接口访问（需要认证）",
                                "  curl http://localhost:8000/admin  # 将失败",
                                "  curl -H 'Authorization: Bearer admin-token' http://localhost:8000/admin  # 将成功",
                                "  curl http://localhost:8000/api/data  # 将失败",
                                "  curl -H 'Authorization: Bearer admin-token' http://localhost:8000/api/data  # 将成功"
                            ]
                        }
                    ]
                }
            ]
        },
        "file_streaming": {
            "title": "📁 启动文件流处理示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看所有示例",
                        "📥 访问 /download/small 下载小文件",
                        "📥 访问 /download/medium 下载中等文件",
                        "📥 访问 /download/large 下载大文件",
                        "📤 访问 /upload 上传文件",
                        "🔄 访问 /process 查看流式处理",
                        "🔄 访问 /convert 查看格式转换",
                        "🌐 连接 ws://localhost:8000/ws 体验WebSocket上传进度"
                    ]
                }
            ]
        },
        "json_config_demo": {
            "title": "🔧 启动JSON配置演示...",
            "sections": [
                {
                    "type": "subsection",
                    "title": "📋 测试说明:",
                    "items": [
                        "1. 访问 http://localhost:8000 查看主页面",
                        "2. 在页面上点击'连接WebSocket'按钮建立连接",
                        "3. 使用页面上的按钮进行测试:",
                        "   - 点击'执行性能测试'查看JSON序列化性能",
                        "   - 输入消息并点击'发送测试消息'测试回显功能"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "📊 直接API访问:",
                    "items": [
                        "   - http://localhost:8000/api/performance - 性能测试",
                        "   - http://localhost:8000/api/large-data - 大数据处理",
                        "   - http://localhost:8000/api/auto - 自动JSON选择"
                    ]
                },
                {
                    "type": "info",
                    "items": [
                        "💡 提示: 安装 orjson 可获得更好性能: uv sync --extra orjson",
                        "卸载: uv remove orjson --optional orjson"
                    ]
                }
            ]
        },
        "logging_demo": {
            "title": "=== Gua框架日志系统演示 ===",
            "sections": [
                {
                    "type": "info",
                    "items": [
                        "访问以下URL测试不同功能:",
                        "  http://localhost:8000/ - 基础日志",
                        "  http://localhost:8000/slow - 慢请求检测",
                        "  http://localhost:8000/error - 错误处理",
                        "  http://localhost:8000/custom - 自定义日志",
                        "  http://localhost:8000/stats - 性能统计",
                        "  http://localhost:8000/json-logs - JSON格式日志",
                        "  ws://localhost:8000/ws - WebSocket日志"
                    ]
                }
            ]
        },
        "new_api_demo": {
            "title": "🚀 Gua框架新API演示",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看主页",
                        "📡 访问 /stream 查看流式响应",
                        "🔥 访问 /sse 查看SSE事件",
                        "🌐 访问 /ws 连接WebSocket",
                        "🔒 访问 /protected 查看受保护的路由"
                    ]
                }
            ]
        },
        "production_logging": {
            "title": "=== Gua框架日志系统 - 生产环境配置 ===",
            "sections": [
                {
                    "type": "info",
                    "items": [
                        "日志将写入文件: app.log",
                        "访问以下端点测试功能:",
                        "  http://localhost:8000/ - 首页",
                        "  http://localhost:8000/api/users - 用户API",
                        "  http://localhost:8000/api/orders - 订单API（可能出错）",
                        "  http://localhost:8000/health - 健康检查",
                        "  http://localhost:8000/metrics - 性能指标"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "生产环境特性:",
                    "items": [
                        "- 文件日志输出",
                        "- 严格的慢请求检测（>0.8秒）",
                        "- 业务指标记录",
                        "- 全局错误处理",
                        "- 性能监控"
                    ]
                }
            ]
        },
        "semantic_streaming": {
            "title": "🎯 启动Linus式语义一致性流式处理演示...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看所有演示"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "🔄 流式演示:",
                    "items": [
                        "  ⚡ /realtime-stream - 零延迟流演示",
                        "  📦 /small-buffer-stream - 低延迟流演示",
                        "  📦 /medium-buffer-stream - 平衡模式流演示",
                        "  📦 /large-buffer-stream - 高吞吐流演示"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "🎯 缓冲效果实时演示 (核心功能):",
                    "items": [
                        "  ⚡ /buffer-demo/0 - 零延迟模式 (立即发送)",
                        "  📦 /buffer-demo/4096 - 低延迟模式 (10ms刷新)",
                        "  📦 /buffer-demo/16384 - 平衡模式 (10ms刷新)",
                        "  📦 /buffer-demo/65536 - 高吞吐模式 (10ms刷新)"
                    ]
                },
                {
                    "type": "subsection",
                    "title": "💡 Linus式设计原则:",
                    "items": [
                        "  ✅ 代码行为与HTTP头承诺一致",
                        "  ✅ 不欺骗用户，语义明确",
                        "  ✅ 简单胜过复杂",
                        "  ✅ buffer_size真正控制缓冲行为！"
                    ]
                }
            ]
        },
        "sender_demo": {
            "title": "📤 启动响应发送示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看主页",
                        "👥 访问 /api/users 查看用户API",
                        "❌ 访问 /api/error 查看错误处理",
                        "🔧 访问 /custom 查看自定义响应",
                        "🔒 访问 /protected 查看受保护的数据（需要认证）",
                        "🌐 连接 /ws 体验WebSocket"
                    ]
                },
                {
                    "type": "info",
                    "items": [
                        "认证提示：在请求头中添加 'Authorization: Bearer secret-token'",
                        "curl示例: curl -H 'Authorization: Bearer secret-token' http://localhost:8000/protected"
                    ]
                }
            ]
        },
        "simple_logging": {
            "title": "=== Gua框架日志系统 - 最简使用 ===",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "访问 http://localhost:8000/ 查看自动日志记录",
                        "访问 http://localhost:8000/api/users 查看API日志",
                        "连接 ws://localhost:8000/ws 查看WebSocket日志"
                    ]
                },
                {
                    "type": "info",
                    "items": [
                        "日志会自动记录：",
                        "- 请求开始时间和参数",
                        "- 响应状态和耗时",
                        "- 慢请求警告（>1秒）",
                        "- 错误详情和堆栈",
                        "- WebSocket连接生命周期"
                    ]
                }
            ]
        },
        "user_centric_logging_demo": {
            "title": "🎯 启动用户中心日志演示...",
            "sections": [
                {
                    "type": "routes",
                    "items": [
                        "📍 访问 http://localhost:8000 查看演示页面",
                        "📊 查看控制台输出，观察用户中心的日志信息",
                        "🔍 所有日志都包含 'user_impact' 字段，说明对用户的影响"
                    ]
                }
            ]
        }
    }

    def _show_example_info(self, app: str, config: Dict[str, Any], cmd: List[str]) -> None:
        """显示示例启动信息 - 数据驱动设计
        
        Args:
            app: 应用标识符
            config: 配置字典
            cmd: 生成的命令
        """
        # 提取示例名称
        example_name = app.split(":")[0].replace("examples.", "")
        
        # 获取示例配置，使用默认配置如果找不到
        example_config = self.EXAMPLE_CONFIGS.get(example_name, {
            "title": f"🚀 启动 {example_name} 示例...",
            "sections": [
                {
                    "type": "routes",
                    "items": [f"📍 访问 http://localhost:{config['port']} 查看应用"]
                }
            ]
        })
        
        # 显示示例信息
        self._print_example_info(example_config, config, example_name)
    
    def _print_example_info(self, example_config: Dict[str, Any], config: Dict[str, Any], example_name: str) -> None:
        """打印示例信息
        
        Args:
            example_config: 示例配置
            config: 配置字典
            example_name: 示例名称
        """
        # 打印标题
        print(example_config["title"])
        
        # 打印各个部分
        for section in example_config.get("sections", []):
            self._print_section(section)
        
        # 显示启动命令
        print("\n启动命令:")
        print(f"  gua examples.{example_name}:app --mode {config['mode']}")
    
    def _print_section(self, section: Dict[str, Any]) -> None:
        """打印单个部分
        
        Args:
            section: 部分配置
        """
        section_type = section["type"]
        
        if section_type == "separator":
            char = section.get("char", "=")
            length = section.get("length", 50)
            print(char * length)
        
        elif section_type == "info":
            for item in section.get("items", []):
                print(item)
        
        elif section_type == "routes":
            for item in section.get("items", []):
                print(item)
        
        elif section_type == "subsection":
            title = section.get("title", "")
            if title:
                print(title)
            
            # 打印子部分
            for subsection in section.get("sections", []):
                self._print_section(subsection)
            
            # 打印当前部分的条目
            for item in section.get("items", []):
                print(item)
            
            if title:
                print()  # 子标题后添加空行


def main() -> int:
    """CLI 入口点"""
    cli = GuaCLI()
    return cli.run()


if __name__ == "__main__":
    sys.exit(main())